package com.tongcao.cn.algorithm.designMoel.proxy.jdk;

import com.tongcao.cn.algorithm.designMoel.proxy.jdk.cglib.CGLibProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * @Author:tongcao
 * @Date:2019/4/10 10:44
 * Description:
 */
public class Client {


    /**
     * 同时我们一定要记住，通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象，它并不是我们的InvocationHandler类型，也不是我们定义的那组接口的类型，而是在运行是动态生成的一个对象，并且命名方式都是这样的形式，以$开头，proxy为中，最后一个数字表示对象的标号。
     *
     * @param args
     */
    public static void main(String[] args) {
//        cglibProxyTest();
        System.out.println("\r\n\r\n\r\n");
        jdkProxyTest();
    }

    private static void cglibProxyTest() {
        System.out.println("**********************CGLibProxy**********************");
        final CGLibProxy cgLibProxy = new CGLibProxy();
        Subject sub = (Subject) cgLibProxy.createProxyObject(new RealSubject());
        System.out.println(sub.getClass().getName());
        sub.rent();
        sub.say("hello wolrd");
    }

    /**
     * * 通过Proxy的newProxyInstance方法来创建我们的代理对象，我们来看看其三个参数
     * * 第一个参数 handler.getClass().getClassLoader() ，我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
     * * 第二个参数realSubject.getC`lass().getInterfaces()，我们这里为代理对象提供的接口是真实对象所实行的接口，表示我要代理的是该真实对象，这样我就能调用这组接口中的方法了
     * * 第三个参数handler， 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
     */
    private static void jdkProxyTest() {
        //创造我门要代理的真实的对象
        Subject realSubject = new RealSubject();

        InvocationHandler handler = new JdkProxy(realSubject);

        Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);
        System.out.println(subject.getClass().getName());
        subject.rent();
//        subject.say("helloWorld");
    }
}